#-------------------------------------
# Cosm Parameter Validation procedures
#-------------------------------------
Function validate-interval ($interval){
	#Accepts Cosm interval parameter or a null value
	#Returns the integer value as interpreted by Cosm (rounding interval up to only seleted values)
	Switch ($interval) {
		{$_ -eq $null} 	{$intervalINT=0; 	 break}
		{$_ -isnot [int]} {Throw "Interval must be specified as an integer"}
		0 				{$intervalINT=0; 	 break}
		{$_ -le 30} 	{$intervalINT=30; 	 break}
		{$_ -le 60} 	{$intervalINT=60; 	 break}
		{$_ -le 300} 	{$intervalINT=300; 	 break}
		{$_ -le 900} 	{$intervalINT=900; 	 break}
		{$_ -le 3600} 	{$intervalINT=3600;  break}
		{$_ -le 10800} 	{$intervalINT=10800; break}
		{$_ -le 21600} 	{$intervalINT=21600; break}
		{$_ -le 43200} 	{$intervalINT=43200; break}
		default 		{$intervalINT=86400; break}
	}
	Return [int]$intervalINT
}	#end function validate-interval

function validate-duration ($duration, $interval) {
	#Accepts Cosm parameters for duration and interval or null values 
	#Returns the equivalent timespan value and the maximum duration associated with the interval or throws an error
	if ($duration -eq $null) {$durationTS=$null} #duration was not specified
	elseif ($duration -is [timespan]) { #set durationTS 
		$durationTS=[timespan]$duration
	} # duration provided as a timespan object
	elseif ($duration -is [string]) { # parse string for Cosm formatted duration
		if ($duration -match "(\A\d{1,})(.*)") { #split duration into value and units
			$value=[int]$Matches[1]
			$Units=$Matches[2]
			if ($units -match "\A(seconds)|(minutes?)|(hours?)|(days?)|(weeks?)|(months?)|(years?)\Z") {
				switch ([int]$(@($matches.keys)[0])) {
					1 {$durationTS = New-Timespan -seconds $value; break}
					2 {$durationTS = New-Timespan -minutes $value; break}
					3 {$durationTS = New-Timespan -hours $value; break}
					4 {$durationTS = New-Timespan -days $value; break}
					5 {$durationTS = New-Timespan -days $value*7; break}
					6 {$durationTS = New-Timespan -days $value*31; break}
					7 {$durationTS = New-Timespan -days $value*365; break}
					default {Throw "should never get here"}
				} #set Timespan = duration
			} #valid duation found
			else {throw "duration parameter has invalid units"
			} # duration parameter has unrecognised units
		}
	} #Duration provided as a string like '6hours'
	else { #report as error
		throw "duration parameter is not valid string or timespan"
	} #duration paramter unrecognised type
	# 2. Cosm won't return any data if you ask for too much. Set max duration to maximum permitted for selected interval
	#		}
	Switch ($interval) {
		{$_ -eq $null}	{$DurationMax = "6hours";	$DurationMaxTS = New-Timespan -hours 6;		break}
		0 				{$DurationMax = "6hours";	$DurationMaxTS = New-Timespan -hours 6;		break}
		{$_ -le 30} 	{$DurationMax = "12hours";	$DurationMaxTS = New-Timespan -hours 12;	break}
		{$_ -le 60} 	{$DurationMax = "24hours";	$DurationMaxTS = New-Timespan -days 1;		break}
		{$_ -le 300} 	{$DurationMax = "5days";	$DurationMaxTS = New-Timespan -days 5;		break}
		{$_ -le 900} 	{$DurationMax = "14days";	$DurationMaxTS = New-Timespan -days 14;		break}
		{$_ -le 3600} 	{$DurationMax = "31days";	$DurationMaxTS = New-Timespan -days 31;		break}
		{$_ -le 10800} 	{$DurationMax = "90days";	$DurationMaxTS = New-Timespan -days 90;		break}
		{$_ -le 21600} 	{$DurationMax = "180days";	$DurationMaxTS = New-Timespan -days 180;	break}
		{$_ -le 43200} 	{$DurationMax = "1year";	$DurationMaxTS = New-Timespan -days 365;	break}
		default		 	{$DurationMax = "1year";	$DurationMaxTS = New-Timespan -days 365;	break}
	}
	$durationTS
	$DurationMaxTS
	$DurationMax
}

function validate-timeperiod ($start, $end, $duration) {	
	# Accepts parameters for start, end and duration, any or all can be null; start and end must be earlier than now 
	# duration must be a timestamp (Cosm duration string not accepted), 
	# start and end may represent a date and time either as a datetime or a string. 
	#They may contain ISO8601 timezone information, If not will be interpreted as Local time on the PC
	# Returns consistent set for start, end and duration as it would be interpreted by Cosm
	if($start -ne $null) { #start not null
		if ($start -gt (get-date)) {Throw " Start Date: Can't be later than current time"}
		$startDT=[datetime](get-date $start).touniversaltime()
		if ($end -ne $null) {
			if ($end -gt (get-date)) {Write-Host " End Date adjusted: Can't be later than current time. "; $end = (get-Date)}
			$endDT=[datetime](get-date $end).touniversaltime()
			if ($duration -ne $null) {Throw "Error in supplied pameters: Can specify only two of start/end/duration"	}#start	/end/ duration not null -- error will be returned by Cosm
			else {$durationTS = [timespan]($endDT - $startDT)}#start/end not null /duration is null -- calc duration
		} # start not null /end not null	
		else { #end is null
			if ($duration -ne $null ) {
				$durationTS = [timespan]$duration  # TS was calc previously
				$endDT=[datetime]($startDT + $durationTS).touniversaltime()
			}#start not null/end is null/duration not null -- calc end
			else { #duration is null
				$endDT=[datetime](get-date).touniversaltime()
				$durationTS = [timespan]($endDT - $startDT)
			}#start not null/end+duration=null -- default end calc duration
		}#start not null/end isnull
	} #start not null
	else { #start is null
		if ($end -ne $null) { #end is not null
			$endDT=[datetime]$end.touniversaltime()
			if ($duration -ne $null) { #duration not null
				$durationTS=[timespan]$duration
				$startDT=[datetime]($end - $durationTS).touniversaltime()
			} #start is null/end is not/duration is not -- calc start
			else { # duration is null
				write-Host "reqesting history query with only an end date - will return no datapoints but is not illegal"
			}# start is null/end id not;/duration is null -- ok but no data
		} #start null / end not null
		else { # end is null
			if ($duration -ne $null){
				$durationTS=[timespan]$duration
				$endDT=[datetime](get-Date).touniversaltime()
				$startDT=[datetime]($endDT-$durationTS).touniversaltime()
			}#start/end null/duration is not -- Default end calc start (Cosm interpretation)
			else {
				$durationTS=new-TimeSpan -Days 0
				$startDT=[datetime](get-Date)
				$endDT=[datetime]$startDT
			}#start/end/duration are null -- this is a non-history query returns current value only in xml (for csv not distnguishable from datapoint
		} #start null/end null
	}#start is null
	$startDT
	$endDT
	$durationTS
}

Function validate-timezone ($timezone) {
	switch ($timezone) {
		$null {$timezoneSTR=""; break}
		{$_ | isnumeric }	{if ([decimal]$_ -gt 13 -or [decimal]$_ -lt -11) {throw "Invalid timezone parameter $_. Must be between -11 and 13"; break}
								else {$timezoneSTR="{0:N2}" -f $([math]::round([decimal]$_*2))/2 ; break	}
							}
		{$_ -is [Datetime]} {break}
		default{$timezoneSTR= $_; break}
	}
	return $timezoneSTR
}

